package 题目集.动态规划.状压dp;

import java.util.Arrays;
import java.util.Scanner;

/**
 * dp版本
 */
public class ch04_蒙德里安的梦想_dp {
	static int n, m;
	static int originState;
	static int maxN = 11;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		while (true) {
			n = sc.nextInt();
			m = sc.nextInt();
			if (n == 0)
				return;
			originState=(1<<n)-1;
			long res = dp();
			System.out.println(res);
		}
	}

	public static long dp() {
		long[][] dp=new long[2][1<<n];
		int pre,cur=0;
		dp[0][originState]=1;
		int state=originState;
		for(int i=1;i<=m;i++) {
			pre=cur;cur=(cur+1)%2;
			dp[cur][0]=dp[pre][state];
			//枚举当前列所有合法的state
			for(int curState=state;curState>0;curState=(curState-1)&state) {
				int choseAll=~curState&state;
				dp[cur][curState]=dp[pre][choseAll];
				
				for(int chose=curState;chose>0;chose=(chose-1)&curState) {
					if(check(chose)) {
						dp[cur][curState]+=dp[pre][chose|choseAll];
					}
				}
			}
		}
		return dp[cur][originState];
	}

	/**
	 * 当前列是否可以被竖条全部插满，即判断是否不存在奇数的空格
	 * 
	 * @param state
	 * @return
	 */
	public static boolean check(int state) {
		int pre = 0;
		for (int i = 0; i < n; i++) {
			int tag = 1 << i;
			// 之前的连续的空格是否为偶数
			if ((tag & state) == 0) {
				if (pre % 2 != 0)
					return false;
			} else {
				pre++;
			}
		}
		return pre % 2 == 0;
	}
}
